package com.mals.pingpong;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

/**
 * Main view of this application. This is also the listener of the ORIENTATION
 * sensor and detects touch move events (finger touch) to update the ball
 * position.
 * 
 * @author marcosal
 * 
 */
public class PingPongView extends SurfaceView implements
		SurfaceHolder.Callback, SensorEventListener {

	// Reference to the AnimationThread. We need to consume the setters
	// exposed by the thread to update some values according to the
	// sensor events and touch move event.
	private PingPongThread thread;
	private float[] mGravity;
	private float[] mGeomagnetic;

	/**
	 * Constructor.
	 * 
	 * @param context
	 */
	public PingPongView(Context context) {
		super(context);
		getHolder().addCallback(this);

		// we need a reference to the display in order to get the real screen
		// width
		// and height.
		Display display = ((WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
		
		DisplayMetrics outMetrics = new DisplayMetrics();
		display.getMetrics(outMetrics);

		thread = new PingPongThread(getHolder(), outMetrics.widthPixels,
				outMetrics.heightPixels);
	}

	/**
	 * Listen the touch events by we just need to use the move event. This means
	 * that we just expect events where the user touch the screen and moves the
	 * finger.
	 * 
	 * @param event
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_MOVE) {
			thread.setBallxpos((int) event.getX());
			thread.setBallypos((int) event.getY());
		}
		return true;
	}

	/**
	 * When the surface is created then we start the thread.
	 * 
	 * @param holder
	 */
	public void surfaceCreated(SurfaceHolder holder) {
		thread.setRunning(true);
		thread.start();
	}

	/**
	 * When the surface is destroyed we have a change to perform some cleaning
	 * routines and do other things like persist information,etc.
	 */
	public void surfaceDestroyed(SurfaceHolder holder) {
		boolean retry = true;
		thread.setRunning(false);
		while (retry) {
			try {
				thread.join();
				retry = false;
			} catch (InterruptedException e) {
				// we will try it again and again...
			}
		}
	}

	/**
	 * Listener for the sensor events.
	 */
	public void onSensorChanged(SensorEvent event) {

		if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
			mGravity = event.values;
		}
		if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
			mGeomagnetic = event.values;
		}

		if (mGravity != null && mGeomagnetic != null) {
			float R[] = new float[16];
			float I[] = new float[16];
			boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
					mGeomagnetic);
			if (success) {
				float inclination[] = new float[3];
				inclination = SensorManager.getOrientation(R, inclination);
				thread.setBarlypos(inclination[1]);
				thread.setBarrypos(inclination[1]);
				thread.setBaruxpos(inclination[1]);
				thread.setBardxpos(inclination[1]);
				System.out.println("inclination[1]: " + inclination[1]);
				
				
			}
		}

	}

	/**
	 * method defined in the SensorEventListener interface.
	 */
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
	}

	/**
	 * Method defined in the SurfaceHolder.Callback interface.
	 */
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
	}

}
